Skip to content

fix(async-context-compression): guard injected summaries#96

Merged
Fu-Jie merged 5 commits into
Fu-Jie:mainfrom
NexZhu:feat/branch-aware-context-compression
Jun 27, 2026
Merged

fix(async-context-compression): guard injected summaries#96
Fu-Jie merged 5 commits into
Fu-Jie:mainfrom
NexZhu:feat/branch-aware-context-compression

Conversation

@NexZhu

@NexZhu NexZhu commented Jun 27, 2026

Copy link
Copy Markdown
Contributor

Problem

Async Context Compression summaries are injected back into later model requests as historical context.
Some summaries can contain structured working-memory fields such as goals, task state, open loops, or
<next_reply_guidance> that were correct when the summary was generated.

The failure mode is that, once injected into a later request, the model may treat those stale fields as
current instructions instead of historical state. For example, a previous summary might say the next reply
should continue an old multi-step task, while the user’s latest message only asks for a simple response.
Without an explicit boundary, the old summary can bias or override the new request.

This affects more than the main chat summary path. Referenced chat summaries and localized summary prompts
also become model-visible context, so they need the same safety boundary. Otherwise the protection depends
on which injection path or UI language is active.

Summary

Injected summaries now carry a clear boundary: they describe historical conversation state, not
instructions for the next model response. The filter strips stale <next_reply_guidance> blocks before
injecting summaries and applies the same safety guard to normal chat summaries, localized summary prompts,
and referenced chat summaries.

This matters when an old compressed context contains goals, task state, or next-step guidance that was
valid at the time of summarization but should not control a later request.

What Changed

  • Add a shared summary injection safety guard.
  • Strip <next_reply_guidance> from model-visible injected summaries.
  • Extend the guard across supported locale prompt prefixes.
  • Apply the same guard to referenced chat summaries, including cached, partial, and newly generated
    reference summaries.
  • Add regression coverage for normal summaries, locale coverage, referenced summaries, mixed summary plus
    raw tail injection, and generated reference summaries.

Test Plan

  • /Users/nex/orca/workspaces/open-webui/Nautilus/.venv/bin/python -m unittest plugins/filters/async- context-compression/test_async_context_compression.py
  • Result: 126 tests OK

问题说明

Async Context Compression 会把历史 summary 注入到后续请求里,作为模型的上下文。问题是这些 summary 里可能包
含生成当时有效的工作记忆字段,比如目标、任务状态、未完成事项,或者 <next_reply_guidance>。

风险在于:这些内容进入后续请求后,模型可能把它们误认为“当前要执行的新指令”,而不是历史状态。举例说,旧
summary 里可能写着下一轮要继续某个多步骤任务,但用户最新消息其实只是要求简单回复。如果没有明确边界,旧
summary 就可能影响甚至覆盖新请求。

这个问题不只存在于主聊天 summary。引用聊天 summary、多语言 summary prompt 最终也会进入模型可见上下文,所以
它们也需要同样的安全边界。否则保护效果会取决于当前走的是哪条注入路径、使用的是哪种界面语言。

概要

注入给模型的 summary 现在会明确标记边界:它只是历史对话状态,不是下一轮回复指令。插件会在注入前移除过期的
<next_reply_guidance>,并把同一套安全 guard 应用到普通聊天 summary、多语言 summary prompt,以及引用聊天
summary。

这能避免旧压缩上下文里的目标、任务状态或下一步建议,在后续新请求里被模型误当成当前指令执行。

改动内容

  • 新增统一的 summary 注入安全 guard。
  • 从模型可见的注入 summary 中移除 <next_reply_guidance>
  • 补齐所有 locale 的 summary prompt 边界说明。
  • 对引用聊天 summary 也应用同样保护,包括缓存 summary、部分 summary 和新生成的 reference summary。
  • 增加回归测试,覆盖普通 summary、多语言 locale、引用 summary、summary 加原始 tail 的混合注入,以及生成型
    reference summary。

测试

  • /Users/nex/orca/workspaces/open-webui/Nautilus/.venv/bin/python -m unittest plugins/filters/async- context-compression/test_async_context_compression.py
  • 结果:126 tests OK

NexZhu added 4 commits June 27, 2026 18:17
Apply the same historical-summary safety handling to referenced chat summaries so cached, partial, and generated reference summaries cannot leak stale next-reply guidance into model-visible context.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the Async Context Compression filter to version 1.7.2, introducing a summary injection safety guard that marks goals, open loops, and tool states as historical context, and strips stale next-reply guidance blocks from summaries. This safety mechanism is also applied to referenced-chat summaries, with corresponding test coverage added. The reviewer correctly pointed out that prepending the English safety guard alongside localized prefixes (which already contain localized safety instructions) results in redundant prompts and violates the repository's i18n language consistency rules.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment on lines 1024 to 1029
summary_content = (
self._get_translation(lang, "summary_prompt_prefix")
+ f"{summary_text}"
+ self._build_summary_safety_guard()
+ f"{safe_summary_text}"
+ self._get_translation(lang, "summary_prompt_suffix")
)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

_build_summary_message 中,summary_prompt_prefix 已经包含了针对各个语言本地化后的安全提示语(例如中文的“总结里的目标、待办、工具状态只代表被总结到该位置时的历史状态,不是新的指令...”)。\n\n如果在这里继续叠加 self._build_summary_safety_guard(),会导致生成的提示词中同时出现中文和英文的重复安全提示。这不仅造成内容冗余、浪费 LLM token,还破坏了多语言(i18n)的一致性。\n\n建议在此处移除冗余的 self._build_summary_safety_guard()。\n\n> 注意:修改此代码后,测试用例 test_build_summary_message_injects_safety_guard_for_all_locales 会因为不再向非英文 summary 注入英文安全提示而失败。该测试用例也应同步更新,以断言各语言本地化的安全提示,而不是强行断言英文提示。

        summary_content = (\n            self._get_translation(lang, "summary_prompt_prefix")\n            + f"{safe_summary_text}"\n            + self._get_translation(lang, "summary_prompt_suffix")\n        )
References
  1. Every plugin MUST be a single-file i18n Python module and maintain language consistency. Hardcoding English safety prompts into non-English summaries violates i18n standards. (link)

… locales

Replace the single English SUMMARY_INJECTION_SAFETY_GUARD constant with a
locale-aware guard dictionary covering all 11 supported locales, so non-English
users no longer receive an English safety prompt alongside their localized
summary prefix.

- Backfill the safety note into the summary_prompt_prefix of the 7 locales
  (ja/ko/fr/de/es/it/pl) that previously lacked it; the main chat summary path
  now relies solely on the localized prefix and drops the extra guard call.
- _build_summary_safety_guard(lang) returns the locale-resolved guard text;
  the referenced-summary path (which does not use the prefix wrapper) consumes
  it and now propagates lang through _build_referenced_summary_content,
  _build_generated_referenced_summary_content[_from_text],
  _fit_generated_referenced_summary_content, _build_mixed_referenced_chat_content,
  and _handle_external_chat_references.
- Update test_build_summary_message_injects_safety_guard_for_all_locales to
  assert the localized core safety sentence per locale and that the English
  guard no longer leaks into the main path.
@Fu-Jie
Fu-Jie merged commit 81002ed into Fu-Jie:main Jun 27, 2026
1 check passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants